//package com.koyi0000.mq.util.service;
//
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//import org.springframework.util.StringUtils;
//
//import java.lang.reflect.Method;
//import java.lang.reflect.Parameter;
//import java.math.BigDecimal;
//import java.util.ArrayList;
//import java.util.List;
//
///**
// * @author koyi0000
// * Description  Date 2020/9/16 22:04
// **/
//@Aspect
//@Component
//public class DistributedLockAspect {
//
//    private static final Logger LOG = LoggerFactory.getLogger(DistributedLockAspect.class);
//
//    @Autowired
//    private DistributedLockService distributedLockService;
//
//    /**
//     * 定义切入点
//     */
//    @Pointcut("@annotation(com.koyi0000.mq.util.service.DistributedLock)")
//    public void doAspect() {
//    }
//
//    @Around("doAspect()")
//    public Object around(ProceedingJoinPoint point) throws Throwable {
//        MethodSignature signature = (MethodSignature) point.getSignature();
//        Method method = signature.getMethod();
//        if (!method.isAnnotationPresent(DistributedLock.class)) {
//            return point.proceed(); //执行方法
//        }
//        DistributedLock distributedLock = method.getAnnotation(DistributedLock.class);
//        //lock: 获取锁token
//        String lockName = this.genLockName(point, signature);
//        if (StringUtils.isEmpty(lockName)) {
//            return point.proceed(); //执行方法
//        }
//        LOG.info("@DistributedLock --- around lockName : {}", lockName);
//        String lockToken = this.distributedLockService.acquire(
//                lockName, distributedLock.lockTimeout(), distributedLock.acquireTimeout());
//        if (lockToken == null) {
//            throw new Exception("获取锁失败");
//        }
//        try {
//            //lock: 业务处理
//            return point.proceed(); //执行方法
//        } finally {
//            // lock: 释放锁
//            if (distributedLock.asnycRelease() == 0) {
//                this.distributedLockService.release(lockName, lockToken);
//            } else {
//                this.distributedLockService.release(lockName, lockToken, distributedLock.asnycRelease());
//            }
//        }
//    }
//
//    /**
//     * 生成 锁名称
//     *
//     * @param point
//     * @param signature
//     * @return
//     */
//    private String genLockName(ProceedingJoinPoint point, MethodSignature signature) {
//        Method method = signature.getMethod();
//        List<String> lockNames = new ArrayList<>();
//        lockNames.add(signature.getDeclaringType().getName());
//        lockNames.add(method.getAnnotation(DistributedLock.class).value());
//        Parameter[] parameters = method.getParameters();
//        if (parameters != null) {
//            for (int i = 0; i < parameters.length; i++) {
//                Parameter parameter = parameters[i];
//                if (parameter.isAnnotationPresent(LockKey.class)) {
//                    Object arg = point.getArgs()[i];
//                    if (arg == null) {
//                        continue;
//                    }
//                    if (Reflect.isPrimitive(arg) || arg instanceof String
//                            || arg instanceof Enum || arg instanceof BigDecimal) {
//                        lockNames.add(String.valueOf(arg));
//                    } else {
//                        String[] fields = parameter.getAnnotation(LockKey.class).value();
//                        List<String> fieldValues = this.genFieldValues(arg, fields);
//                        if (fieldValues != null) {
//                            lockNames.addAll(fieldValues);
//                        }
//                    }
//                }
//            }
//        }
//        return AtUtils.formatByStrs(lockNames);
//    }
//
//    /**
//     * 生成字段值列表
//     *
//     * @param obj
//     * @param fields
//     * @return
//     */
//    private List<String> genFieldValues(Object obj, String[] fields) {
//        if (fields == null || fields.length == 0) {
//            return null;
//        }
//        List<String> fieldValues = new ArrayList<>();
//        for (String field : fields) {
//            Result<Object> fieldValueResult = Reflect.getFieldValue(obj, field);
//            if (fieldValueResult.isSuccess()) {
//                Object fieldValue = fieldValueResult.getObject();
//                if (fieldValue == null) {
//                    continue;
//                }
//                if (Reflect.isPrimitive(fieldValue) || fieldValue instanceof String
//                        || fieldValue instanceof Enum || fieldValue instanceof BigDecimal) {
//                    fieldValues.add(String.valueOf(fieldValue));
//                }
//            }
//        }
//        return fieldValues;
//    }
//}
